"""
配置管理模块

负责读取和管理MiniCoder CLI的配置文件。
"""

import os
from pathlib import Path
from typing import Any, Dict, Optional

import yaml

# 尝试导入rich，如果失败则使用标准输出
try:
    from rich.console import Console
    console = Console()
    USE_RICH = True
except ImportError:
    USE_RICH = False
    console = None


def print_message(message: str, style: str = "") -> None:
    """打印消息，支持rich和标准输出"""
    if USE_RICH and console:
        console.print(message, style=style)
    else:
        print(message)


class Config:
    """配置管理类"""
    
    DEFAULT_CONFIG = {
        "models": {
            "openrouter": {
                "api_key": "",
                "base_url": "https://openrouter.ai/api/v1",
                "default_model": "openai/gpt-4"
            },
            "ollama": {
                "base_url": "http://localhost:11434",
                "default_model": "codellama"
            },
            "siliconflow": {
                "api_key": "",
                "base_url": "https://api.siliconflow.cn",
                "default_model": "Qwen/Qwen3-Coder-30B-A3B-Instruct",
                "api_style": "openai"
            }
        },
        "default_provider": "siliconflow",
        "ui": {
            "theme": "default",
            "show_tokens": False,
            "max_context_size": 8192
        }
    }
    
    def __init__(self, config_path: Optional[Path] = None) -> None:
        """
        初始化配置管理器
        
        Args:
            config_path: 配置文件路径，如果为None则使用默认路径
        """
        self.config_path = config_path or self._get_default_config_path()
        self._config = self._load_config()
    
    @staticmethod
    def _get_default_config_path() -> Path:
        """获取默认配置文件路径"""
        # 优先使用用户主目录下的配置
        home_config = Path.home() / ".minicoder" / "config.yaml"
        if home_config.exists():
            return home_config
        
        # 否则使用当前目录下的配置
        return Path("config.yaml")
    
    def _load_config(self) -> Dict[str, Any]:
        """加载配置文件"""
        if not self.config_path.exists():
            # 如果配置文件不存在，创建默认配置
            self._create_default_config()
        
        try:
            with open(self.config_path, 'r', encoding='utf-8') as f:
                config = yaml.safe_load(f)
            
            # 合并默认配置，确保所有必要的键都存在
            return self._merge_config(self.DEFAULT_CONFIG, config or {})
            
        except Exception as e:
            print_message(f"警告: 配置文件加载失败，使用默认配置: {e}", "yellow")
            return self.DEFAULT_CONFIG.copy()
    
    def _create_default_config(self) -> None:
        """创建默认配置文件"""
        try:
            # 确保目录存在
            self.config_path.parent.mkdir(parents=True, exist_ok=True)
            
            # 写入默认配置
            with open(self.config_path, 'w', encoding='utf-8') as f:
                yaml.dump(self.DEFAULT_CONFIG, f, default_flow_style=False, allow_unicode=True)
            
            print_message(f"已创建默认配置文件: {self.config_path}", "green")
            
        except Exception as e:
            raise RuntimeError(f"无法创建配置文件: {e}")
    
    def _merge_config(self, default: Dict[str, Any], user: Dict[str, Any]) -> Dict[str, Any]:
        """递归合并配置"""
        result = default.copy()
        
        for key, value in user.items():
            if key in result and isinstance(result[key], dict) and isinstance(value, dict):
                result[key] = self._merge_config(result[key], value)
            else:
                result[key] = value
        
        return result
    
    def get(self, key: str, default: Any = None) -> Any:
        """获取配置值"""
        keys = key.split('.')
        value = self._config
        
        try:
            for k in keys:
                value = value[k]
            return value
        except (KeyError, TypeError):
            return default
    
    def set(self, key: str, value: Any) -> None:
        """设置配置值"""
        keys = key.split('.')
        config = self._config
        
        # 导航到父级
        for k in keys[:-1]:
            if k not in config:
                config[k] = {}
            config = config[k]
        
        # 设置值
        config[keys[-1]] = value
    
    def save(self) -> None:
        """保存配置到文件"""
        try:
            with open(self.config_path, 'w', encoding='utf-8') as f:
                yaml.dump(self._config, f, default_flow_style=False, allow_unicode=True)
        except Exception as e:
            raise RuntimeError(f"无法保存配置文件: {e}")
    
    def get_provider(self) -> str:
        """获取默认提供商，优先检查环境变量"""
        # 优先检查环境变量
        env_provider = os.getenv("MINICODER_DEFAULT_PROVIDER")
        if env_provider:
            return env_provider
        
        # 回退到配置文件
        return self.get("default_provider", "openrouter")
    
    def set_provider(self, provider: str) -> None:
        """设置默认提供商"""
        self.set("default_provider", provider)
    
    def get_model(self, provider: Optional[str] = None) -> str:
        """获取默认模型，优先检查环境变量"""
        provider = provider or self.get_provider()
        
        # 优先检查环境变量
        env_model = os.getenv(f"MINICODER_{provider.upper()}_MODEL")
        if env_model:
            return env_model
        
        # 回退到配置文件
        return self.get(f"models.{provider}.default_model", "")
    
    def set_model(self, model: str, provider: Optional[str] = None) -> None:
        """设置默认模型"""
        provider = provider or self.get_provider()
        self.set(f"models.{provider}.default_model", model)
    
    def get_api_key(self, provider: Optional[str] = None) -> str:
        """获取API密钥，优先检查环境变量"""
        provider = provider or self.get_provider()
        
        # 优先检查环境变量
        env_api_key = os.getenv(f"MINICODER_{provider.upper()}_API_KEY")
        if env_api_key:
            return env_api_key
        
        # 回退到配置文件
        return self.get(f"models.{provider}.api_key", "")
    
    def set_api_key(self, api_key: str, provider: Optional[str] = None) -> None:
        """设置API密钥"""
        provider = provider or self.get_provider()
        self.set(f"models.{provider}.api_key", api_key)
    
    def get_base_url(self, provider: Optional[str] = None) -> str:
        """获取基础URL，优先检查环境变量"""
        provider = provider or self.get_provider()
        
        # 优先检查环境变量
        env_base_url = os.getenv(f"MINICODER_{provider.upper()}_BASE_URL")
        if env_base_url:
            return env_base_url
        
        # 回退到配置文件
        return self.get(f"models.{provider}.base_url", "")
    
    def get_provider_config(self, provider: Optional[str] = None) -> Dict[str, Any]:
        """获取提供商配置"""
        provider = provider or self.get_provider()
        return self.get(f"models.{provider}", {})
    
    @staticmethod
    def get_supported_env_vars() -> Dict[str, str]:
        """获取所有支持的环境变量及其说明"""
        return {
            "MINICODER_DEFAULT_PROVIDER": "设置默认AI提供商 (openrouter, ollama, siliconflow)",
            "MINICODER_OPENROUTER_API_KEY": "OpenRouter API密钥",
            "MINICODER_OPENROUTER_MODEL": "OpenRouter默认模型",
            "MINICODER_OPENROUTER_BASE_URL": "OpenRouter API基础URL",
            "MINICODER_OLLAMA_MODEL": "Ollama默认模型",
            "MINICODER_OLLAMA_BASE_URL": "Ollama服务基础URL",
            "MINICODER_SILICONFLOW_API_KEY": "SiliconFlow API密钥",
            "MINICODER_SILICONFLOW_MODEL": "SiliconFlow默认模型",
            "MINICODER_SILICONFLOW_BASE_URL": "SiliconFlow API基础URL"
        }
    
    @classmethod
    def create_default_config(cls, config_path: Optional[Path] = None) -> None:
        """创建默认配置文件"""
        config = cls(config_path)
        config._create_default_config()
